import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 言初
 * Date: 2024-05-06
 * Time: 8:35
 */
public class Main {




    private static RandomAccessFile raf;

    // 使用共享内存的方式来实现进程之间的通信。建议在上次的读者/写者程序上补充完整，尽量落到实处（一个实际应用）。
    // 所以我们应该需要创建4个线程，来完成读者写者模型。
    // 分别来显示 读者和读者，读者和写者，写者和写者之间的关系和处理方式。

    public static void main(String[] args) throws Exception {

     /*   int writenums=0;// 有几个进程在写
        int readnums=0; // 有几个进程在读

        write write1 = new write();
        write2 write2 = new write2();
        write1.func(writenums,readnums);
        write2.func(writenums,readnums);
        read read1 = new read();
        read2 read2 = new read2();
        read1.func(writenums,readnums);
        read2.func(writenums,readnums);*/

        Main.read1();
        Main.read2();
    }


    public static void write1() {
        try {
            // 通过 ProcessBuilder 创建一个新的进程
            ProcessBuilder processBuilder = new ProcessBuilder("notepad.exe");
            Process process = processBuilder.start();

            //获取随机存取文件对象，建立文件和内存的映射，即时双向同步
            raf = new RandomAccessFile("E:/test.txt", "rw");
            FileChannel fc = raf.getChannel();      //获取文件通道
            MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);  //获取共享内存缓冲区
            FileLock flock=null;

            for(int i=65;i<91;i++){
                //阻塞独占锁，当文件锁不可用时，当前进程会被挂起
                flock=fc.lock();
                System.out.println(System.currentTimeMillis() +  ":write1:" + (char)i);
                mbb.put((byte)i);  //往文件中开始写入数据
                flock.release();        //释放锁
                Thread.sleep(1000);
            }

            // 等待进程结束
            int exitCode = process.waitFor();
            System.out.println("write1已结束，退出码为：" + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }


    public static void read1() {
        try {
            // 通过 ProcessBuilder 创建一个新的进程
            ProcessBuilder processBuilder = new ProcessBuilder("notepad.exe");
            Process process = processBuilder.start();

            raf = new RandomAccessFile("E:/test.txt", "rw");
            FileChannel fc = raf.getChannel();
            MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
            FileLock flock=null;

            for(int i=0;i<36;i++){
                flock=fc.lock();    //上锁
                System.out.println( System.currentTimeMillis() +  ":read1:" + (char)mbb.get(i));
                flock.release();    //释放锁
                Thread.sleep(1000);
            }

            // 等待进程结束
            int exitCode = process.waitFor();
            System.out.println("read1已结束，退出码为：" + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void read2() {
        try {
            // 通过 ProcessBuilder 创建一个新的进程
            ProcessBuilder processBuilder = new ProcessBuilder("notepad.exe");
            Process process = processBuilder.start();

            raf = new RandomAccessFile("E:/test.txt", "rw");
            FileChannel fc = raf.getChannel();
            MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
            FileLock flock=null;

            for(int i=0;i<36;i++){
                flock=fc.lock();    //上锁
                System.out.println( System.currentTimeMillis() +  ":read1:" + (char)mbb.get(i));
                flock.release();    //释放锁
                Thread.sleep(1000);
            }

            // 等待进程结束
            int exitCode = process.waitFor();
            System.out.println("read1已结束，退出码为：" + exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}





